package com.browsesoft.htmlcomponent;

import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import com.aote.component.select.SelectContent;
import com.aote.util.StringHelper;
import com.browsesoft.Entity;
import com.browsesoft.Tools;
import com.browsesoft.dbtools.DBTools;
import com.browsesoft.parameter.Parameter;
import com.browsesoft.util.RequestHelper;

public class SelectContentFactory {
	private static SelectContentFactory self = new SelectContentFactory();

	public static SelectContentFactory getInstance() {
		return self;
	}

	private SelectContentFactory() {

	}

	public List getOptions(Element dealElement, HttpServletRequest request,
			Map entityAttrs) {
		List result = new LinkedList();
		try {
			// 从页面上的option和对应的参数值构造
			result = this.getOptionsFromPage(dealElement);
			// 如果有参数标记
			if (dealElement.hasAttribute("param")) {
				// 得到参数
				Parameter parameter = new Parameter(dealElement
						.getAttribute("param"));
				// 得到参数值
				LinkedList list = parameter.getParamValues();
				result.addAll(list);
			}
			// 否则,是SQL语句
			else if (dealElement.hasAttribute("sql")) {
				// 得到SQL语句
				String sql = dealElement.getAttribute("sql");
				// 请求参数替换，实体参数替换
				sql = RequestHelper.replaceParameter(request, sql);
				sql = StringHelper.replaceStr(entityAttrs, sql);
				// 根据sql查询语句得到结果
				String[][] results = DBTools.executeQueryWithTableHead(sql);
				// 根据查询结果产生选择项
				LinkedList list = arrayToList(results);
				result.addAll(list);
			} else if (dealElement.hasAttribute("selectname")) {
				String name = dealElement.getAttribute("selectname");
				// 实现SelectContent接口的类处理
				SelectContent select = (SelectContent) Class.forName(name)
						.newInstance();
				List list = select.getSelectItem(dealElement, request);
				result.addAll(list);
			}
			return result;
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}

	/**
	 * 得到页面上的列表值
	 * 
	 * @param e
	 *            要处理的元素
	 * @return 链表
	 */
	private LinkedList getOptionsFromPage(Element e) {
		// 如果有defaultoptions属性,从defaultoptions中取
		if (e.hasAttribute("defaultoptions")) {
			String defaultoptions = e.getAttribute("defaultoptions");
			return Tools.stringToLinkedList(defaultoptions);
		}
		LinkedList list = new LinkedList();
		NodeList nl = e.getElementsByTagName("option");
		// 对于页面上的每一个选项
		for (int i = 0; i < nl.getLength(); i++) {
			// 得到列表值
			Node node = nl.item(i);
			String option = node.getFirstChild().getNodeValue();
			// 添加到链表中
			list.add(option);
		}
		// 把初始值复制到defaultoptions里,以便后面使用
		String defaultoptions = Tools.LinkedListTostring(list);
		e.setAttribute("defaultoptions", defaultoptions);
		return list;
	}

	/**
	 * 将查询结果的字符串二维数组转换成iterator，iterator中放二维数组从第二行 开始的第一列
	 * 
	 * @param datas
	 *            查询结果的字符串二维数组
	 * @return 二维数组从第二行开始的第一列的列表
	 */
	private LinkedList arrayToList(String[][] datas) {
		LinkedList list = new LinkedList();
		// 对二维数组中从第二行开始的每一行
		for (int i = 1; i < datas.length; i++) {
			// 将第一列存入列表
			list.add(datas[i][0]);
		}
		// 返回列表对应的iterator
		return list;
	}

}
